#include <iostream>
#include <cstdlib>
#include <string>
#include <unistd.h>
#include "XrdDownloadManager.hh"
#include <gapiUI.h>
#include <XrddmConfig.h>
#include "XrdDMLog.hh"

#ifdef HAS_APPMON
#include <ApMon.h>
#endif
using namespace std;

// XrdDMLog *gLog = 0;

#ifdef HAS_APPMON
bool testAppMon() {
    cout << "AppMon is ON ..." << endl;
    return true;
}
#endif

int normalRun ( XrdDownloadManager *dm, string from, string to/*,string cfg*/ ) {
//   dm->ReadConfigFile(cfg);
    dm->PrintXrddmOptions();
    dm->Init();

    int rerValAlien = dm->DoAliEnToken();

    rerValAlien = dm->ConnectToAliEn();
    if ( rerValAlien <= 0 )
        return -1;
//   dm->SetXrdCpOptions(optionsXrdCp);
    dm->SetTimeSeed();
    //   dm->SetDebug(1);
    //   dm->DeleteServersFile();
    dm->UseServersFile();
    dm->UseServersFileTryNewSitesFirst();
    dm->UseFallbackDownload();

    string strAll ( from );

    size_t pos;
    pos = strAll.find ( "alien:///" );
    if ( pos != string::npos ) {
        strAll.erase ( 0, 8 );
        //     cout << strAll.c_str()<< endl;
        dm->AddFileToDownloadFromAliEn ( strAll.c_str() );
//     return dm->DownloadFile(to);
    } else {
        while ( !strAll.empty() ) {
            pos = strAll.find_first_of ( "," );
            dm->AddFileToDownload ( strAll.substr ( 0, strAll.find_first_of ( "," ) ) );
            strAll.erase ( 0, pos + 1 );
            if ( pos > strAll.length() ) {
                dm->AddFileToDownload ( strAll.c_str() );
                break;
            }
        }
    }

//     dm->DownloadFile ( to );
//   return dm->DownloadFile(to)>0?0:-1;
    return 0;
}

int setLogFile ( string logFile ) {



    if ( logFile.empty() ) return 1;

    string logFileAbsolute;
    // Check if log filename is absolute
    if ( ( !logFile.empty() ) && ( logFile.find_first_of ( "/" ) ) ) {
        char path[MAXPATHLEN];
        getcwd ( path, MAXPATHLEN );
        logFileAbsolute = path;
        logFileAbsolute += "/";
        logFileAbsolute += logFile.c_str();
    } else {
        logFileAbsolute = logFile.c_str();
    }

    //umask(0);
//     chdir ( "/" );

 
    if ( !logFileAbsolute.empty() ) {
        if ( !gLog->SetFile ( logFileAbsolute.c_str() ) ) {
            return 21;  // no error message can be seen at this point, it is pointless
            // to print something
        }
    }
}

int setConfigFile(string configFile,XrdDownloadManager *dm) {
    if ( !configFile.empty() ) {
        ifstream ifile ( configFile.c_str() );
        if ( ifile ) {
            dm->ReadConfigFile ( configFile.c_str() );
            dm->InitLogFile();
        }
        else {

            XrdDMLogFatal ( "Config missing !!!!!!" );
            return -1;
        }
    }

    return 0;

}

int main ( int argc, char **argv ) {

    // init XrdDMLog log
return 0;

XrdDMLog::Init();
return 1;
//     XrdDownloadManager *dm = new XrdDownloadManager;
    XrdDownloadManager dm;
    dm.SetTimeSeed();

    string confFile;

    string logFileStr;

    string debugLevelStr;
    int debugLevel=0;
    int index;
    int c;

    opterr = 0;

//     while ( ( c = getopt ( argc, argv, ":c:l:d:x:m::a::s::f::n::A:" ) ) != -1 )
    while ( ( c = getopt ( argc, argv, "c:l:d:x:masfnA" ) ) != -1 )
// 		    printf ("%c\n", c  );
        switch ( c ) {
        case 'c':
            confFile = optarg;
            break;
        case 'l':
            logFileStr = optarg;
            if ( setLogFile ( logFileStr.c_str() ) ) return 32;
            close ( STDIN_FILENO );
            close ( STDOUT_FILENO );
            close ( STDERR_FILENO );
            break;
        case 'd':
            debugLevelStr = optarg;
            debugLevel = atoi ( debugLevelStr.c_str() );
            gLog->SetDebug ( debugLevel );
			dm.SetDebug(debugLevel);
            break;
        case 'x':
            debugLevelStr = optarg;
            dm.SetXrdCpOptionsExtra(debugLevelStr);
            break;
        case 'm':
            XrdDMLogDebugFull ( "Using -m for UseMonalisa ......." );
            dm.UseMonalisa();
            break;
        case 'a':
            XrdDMLogDebugFull ( "Using -a for UseAliEnCp ......." );
            dm.UseAliEnCp();
            break;
        case 's':
            XrdDMLogDebugFull ( "Using -s for UseServersFile ......." );
            dm.UseServersFile();
            break;
        case 'f':
            XrdDMLogDebugFull ( "Using -f for UseFallbackDownload ......." );
            dm.UseFallbackDownload();
            break;
        case 'n':
            XrdDMLogDebugFull ( "Using -n for UseServersFileTryNewSitesFirst ......." );
            dm.UseServersFileTryNewSitesFirst();
            break;
        case 'A':
            XrdDMLogDebugFull ( "Using -A for DoAliEnToken ......." );
            dm.CreateAliEnToken(true);
            break;
        case ':':
            XrdDMLogFatal ( "Option '-%c' requires an argument", optopt );
            return 11;
            break;
        case '?':
            XrdDMLogFatal ( "Unknown option: '-%c'", optopt );
            return 12;
        default:
            abort ();
        }

//     time_t rawtime;
//     struct tm * timeinfo;
//     char buffer [80];
//     time ( &rawtime );
//     timeinfo = localtime ( &rawtime );
//     strftime ( buffer,80,"######## xrddm started at %c ###########",timeinfo );
//     string banner = buffer;
//
//     gLog->SetBanner ( banner.c_str() );
//
//     gLog->PrintBanner();

//     gLog->Info ( "---------------- Copy ---------------",1 );
    string filestr[2];
    int i=0;
    for ( index = optind; index < argc; index++ ) {
        filestr[i++] = argv[index];
    }
//     gLog->Info ( "From : %s",filestr[0].c_str() );
//     gLog->Info ( "To   : %s",filestr[1].c_str() );
//     gLog->Info ( "-------------------------------------",1 );

    dm.SetFileIOFileNames ( filestr[0],filestr[1] );
    if (setConfigFile(confFile,&dm)) return 31;
    dm.Init();

    dm.PrintXrddmOptions();
    dm.PrintDownloadInfo();

    int retValDownload = dm.DownloadFile();

    gLog->Info("xrd-dm %s to %s finished with retval %d log in %s ...",filestr[0].c_str(),filestr[1].c_str(),retValDownload,dm.CurrentLogFileName().c_str());

    XrdDMLog::Delete();
//     delete gLog;
    return retValDownload;
}






int normalRun ( XrdDownloadManager *dm, string from, string to/*,string cfg="xrd-dm.cfg"*/ );


// int mainold(int argc, char **argv)
// {
//
//     XrdDMLog::Init();
//
// #ifdef HAS_APPMON
//     if (testAppMon())
//         cout << "AppMon test passed" << endl;
//     else
//         cout << "AppMon test failed" << endl;
// #endif
//
//     string XRDDMSYS;
//     int retVal = 0;
//     if (getenv("XRDDMSYS"))
//         XRDDMSYS.append(getenv("XRDDMSYS"));
//
//     if (XRDDMSYS.empty()) {
//         cerr << "ERROR: $XRDDMSYS is not set." << endl;
//         return -3;
//     }
//
//     string cfgStr(XRDDMSYS);
//     XrdDownloadManager dm;
//
//     int numfiles = 0;
//     string fileIO[2];
//     string xrdOptions;
//     string argTmp;
//     size_t found;
//
//     if (argc == 1) {
//         cout << "Reading default config file " << XRDDMSYS.c_str() << "/etc/xrd-dm.cfg" << endl;
//         cfgStr.append("/etc/xrd-dm.cfg");
//         dm.ReadConfigFile(cfgStr.c_str());
//         printHelp();
//         dm.Init();
//         dm.DoAliEnToken();
//         return 0;
//     }
//
//     argTmp = argv[1];
//     if ((argc == 3) && (argTmp.find("--config") != string::npos)) {
//         dm.ReadConfigFile(argv[2]);
// //         printHelp();
//         dm.Init();
//         dm.DoAliEnToken();
//         return 0;
//     }
//     else {
//         cfgStr.append("/etc/xrd-dm.cfg");
//         dm.ReadConfigFile(cfgStr.c_str());
//     }
//
//
//     if (dm.GetDebug() > 4)
//         cout << "Number of arguments " << argc << endl;
//     int i = 1;
//     for (i = 1;i < argc;i++) {
//         if (dm.GetDebug() > 4)
//             cout << i << "-- " << endl;
//         argTmp = argv[i];
//
//         if (argTmp.find("--config") != string::npos) {
//             if (dm.GetDebug() > 4)
//                 cout << argv[i] << " " << argv[i+1] << endl;
//             dm.ReadConfigFile(argv[++i]);
// //       printHelp();
//             if (dm.GetDebug() > 4)
//                 cout << i << "-- " << endl;
//             continue;
//         }
//         else if (argTmp.find("--xrdcp-tried") != string::npos) {
//             if (dm.GetDebug() > 4)
//                 cout << "--xrdcp-tried = " << argv[i+1] << endl;
//             dm.SetXrdCpOptionsExtra(argv[++i]);
//         }
//     }
//
//     fileIO[0] = argv[argc-2];
//     fileIO[1] = argv[argc-1];
//     if (dm.GetDebug() > 3)
//         cout << fileIO[0] << " " << fileIO[1] << endl;
//
//     if (fileIO[0].empty() || fileIO[1].empty()) {
//         return 0;
//     }
//     else
//         retVal = normalRun(&dm, fileIO[0], fileIO[1]);
//
//     return retVal;
// }


// void printHelp()
// {
//
//     cout << "xrddm "<< XRDDM_VERSION_MAJOR <<"."<< XRDDM_VERSION_MINOR << endl;
//     cout << "Help: " << endl;
//     cout << "\txrd-dm root://<redirector1>:<port>/<path>,root://<redirector2>:<port>/<path>,...,root://<redirectorN>:<port>/<path> <path>" << endl;
//     cout << "or" << endl;
//     cout << "\txrd-dm alien://<alien_path> <path_with_filename>" << endl;
//     cout << endl;
// }
